package com.dy.vueadminservice.service.users.impl;

import com.dy.vueadminservice.dao.UserDao;
import com.dy.vueadminservice.model.user.Permission;
import com.dy.vueadminservice.model.user.Role;
import com.dy.vueadminservice.service.users.UserInfoService;
import com.dy.vueadminservice.service.users.dto.UserDTO;
import com.dy.vueadminservice.service.users.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.*;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: huangdeyao
 * @create: 2018-09-11 11:44
 **/
@Service
public class UserInfoServiceImpl implements UserInfoService, UserDetailsService {

    private final UserDao userDao;
    private final PasswordEncoder passwordEncoder;
    private final UserMapper userMapper;

    @Autowired
    public UserInfoServiceImpl(UserDao userDao, PasswordEncoder passwordEncoder, UserMapper userMapper) {
        this.userDao = userDao;
        this.passwordEncoder = passwordEncoder;
        this.userMapper = userMapper;
    }

    @Override
    public com.dy.vueadminservice.model.user.User findByUsername(String username) {
        return userDao.findByUsername(username);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查找用户信息
        //根据查找到的用户信息判断用户是否被冻结
        com.dy.vueadminservice.model.user.User user = findByUsername(username);
        if (user == null) {
            throw new InternalAuthenticationServiceException("登录账户信息错误");
        }
        user.setPassword(passwordEncoder.encode("123456"));
        return new User(user.getUsername(), user.getPassword(),
                user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(),
                mapToGrantedAuthorities(user));
    }


    public Collection<GrantedAuthority> mapToGrantedAuthorities(com.dy.vueadminservice.model.user.User user) {
        Set<Role> roles = user.getRoles();
        Set<String> permissions = roles.stream().flatMap(role -> role.getPermissions().stream())
                .map(Permission::getName)
                .collect(Collectors.toSet());
        permissions.forEach(System.out::println);
        return roles.stream().flatMap(role -> role.getPermissions().stream())
                .map(permission -> new SimpleGrantedAuthority(permission.getName()))
                .collect(Collectors.toList());
    }

    @Override
    public UserDTO getInfo() {
        com.dy.vueadminservice.model.user.User users = findByUsername(userName());
        if (users == null) {
            return null;
        }
        Set<Role> roles = users.getRoles();
        Set<String> permission = roles.stream().flatMap(role -> role.getPermissions().stream())
                .map(Permission::getName)
                .collect(Collectors.toSet());
        users.setPermission(permission);
        return userMapper.toDto(users);
    }


    @Override
    public String userName() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            UserDetails userDetails = ((UserDetails) principal);
            return userDetails.getUsername();
        } else if (principal instanceof String) {
            return (String) principal;
        }
        return null;
    }


    /**
     * 刷新权限
     */
    @Override
    public void refreshPermission(HttpServletRequest request) {
//        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
//        SecurityContextHolder.getContext().setAuthentication(authentication);


//        // 得到当前的认证信息
//        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
////        //  生成当前的所有授权UsernamePasswordAuthenticationToken
//        List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
//        // 添加 ROLE_VIP 授权
//        updatedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
//        // 重置认证信息
//        SecurityContext context =  SecurityContextHolder.getContext();
//        // 生成新的认证信息
//        Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities);
//        context.setAuthentication(newAuth);
//        System.out.println("context = " + context);
//        HttpSession session = request.getSession(true);
//        //在session中存放security context,方便同一个session中控制用户的其他操作
//        session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());


//        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
//        if (auth != null) {
//            //  生成当前的所有授权UsernamePasswordAuthenticationToken
//            List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
//            // 添加 ROLE_VIP 授权
//            updatedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
//            // 重置认证信息
//            // 生成新的认证信息
//            auth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities);
//            SecurityContextHolder.getContext().setAuthentication(auth);
//        }

    }

}
